#include <iostream>
#include <sstream>
#include <thread>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <signal.h>
#include <string>

class Server {
public:
    Server();
    ~Server();
    void run(int port = 8080);

private:
    std::string processRequest(const std::string& request);
    std::string handleLogin(const std::string& request);
    std::string handleGetCourses();
    std::string handleSelectCourse(const std::string& request);
    std::string handleIndex();
    std::string createResponse(const std::string& status, const std::string& message, const std::string& data = "");

    int server_fd_;
};

Server::Server() : server_fd_(-1) {
    std::cout << "Server created" << std::endl;
}

Server::~Server() {
    if (server_fd_ >= 0) {
        close(server_fd_);
    }
    std::cout << "Server destroyed" << std::endl;
}

void Server::run(int port) {
    server_fd_ = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd_ < 0) {
        std::cerr << "Socket creation failed" << std::endl;
        return;
    }

    int opt = 1;
    setsockopt(server_fd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(server_fd_, (struct sockaddr*)&address, sizeof(address)) < 0) {
        std::cerr << "Bind failed" << std::endl;
        return;
    }

    if (listen(server_fd_, 10) < 0) {
        std::cerr << "Listen failed" << std::endl;
        return;
    }

    std::cout << "Server running on port " << port << std::endl;
    std::cout << "Press Ctrl+C to stop the server" << std::endl;

    while (true) {
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        int client_fd = accept(server_fd_, (struct sockaddr*)&client_addr, &client_len);

        if (client_fd < 0) continue;

        std::thread([this, client_fd]() {
            char buffer[4096];
            int bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);
            if (bytes_read > 0) {
                buffer[bytes_read] = '\0';
                std::string request(buffer);
                std::string response = processRequest(request);
                write(client_fd, response.c_str(), response.length());
            }
            close(client_fd);
        }).detach();
    }
}

std::string Server::processRequest(const std::string& request) {
    std::istringstream iss(request);
    std::string method, path, version;
    iss >> method >> path >> version;

    if (method == "POST" && path == "/api/login") {
        return handleLogin(request);
    } else if (method == "GET" && path == "/api/courses") {
        return handleGetCourses();
    } else if (method == "POST" && path == "/api/select-course") {
        return handleSelectCourse(request);
    } else if (method == "GET" && path == "/") {
        return handleIndex();
    }

    return createResponse("error", "Endpoint not found");
}

std::string Server::handleLogin(const std::string& request) {
    size_t body_start = request.find("\r\n\r\n");
    if (body_start == std::string::npos) {
        return createResponse("error", "Invalid request");
    }

    std::string body = request.substr(body_start + 4);
    size_t username_pos = body.find("username=");
    size_t password_pos = body.find("password=");

    if (username_pos == std::string::npos || password_pos == std::string::npos) {
        return createResponse("error", "Missing credentials");
    }

    std::string username = body.substr(username_pos + 9, body.find('&', username_pos) - username_pos - 9);
    std::string password = body.substr(password_pos + 9);

    // 硬编码用户验证
    if ((username == "student001" && password == "student123") ||
        (username == "teacher001" && password == "teacher123") ||
        (username == "admin" && password == "admin123")) {

        std::string role = "student";
        int user_id = 3;
        if (username == "teacher001") { role = "teacher"; user_id = 2; }
        else if (username == "admin") { role = "admin"; user_id = 1; }

        std::stringstream ss;
        ss << "{\"success\":true,\"user\":{\"id\":" << user_id
           << ",\"username\":\"" << username << "\",\"role\":\"" << role << "\"}}";
        return createResponse("success", "Login successful", ss.str());
    }

    return createResponse("error", "Invalid credentials");
}

std::string Server::handleGetCourses() {
    // 返回硬编码的课程数据
    std::string courses = R"([
        {"id":1,"course_code":"CS101","course_name":"计算机基础","teacher_name":"李老师","credits":3,"max_students":50,"current_students":0,"semester":"2025春季","classroom":"A101","schedule":"周一 8:00-9:30","status":"可选"},
        {"id":2,"course_code":"CS102","course_name":"数据结构","teacher_name":"李老师","credits":4,"max_students":40,"current_students":0,"semester":"2025春季","classroom":"B201","schedule":"周二 10:00-11:30","status":"可选"},
        {"id":3,"course_code":"CS103","course_name":"数据库原理","teacher_name":"李老师","credits":3,"max_students":45,"current_students":0,"semester":"2025春季","classroom":"C301","schedule":"周五 14:00-15:30","status":"可选"}
    ])";

    return createResponse("success", "Courses retrieved", courses);
}

std::string Server::handleSelectCourse(const std::string& request) {
    // 简化实现，直接返回成功
    return createResponse("success", "Course selected successfully");
}

std::string Server::handleIndex() {
    std::string html = R"html(
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生选课系统</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .login-form, .course-list { margin: 20px 0; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
        .course-item { border: 1px solid #eee; padding: 10px; margin: 10px 0; border-radius: 3px; }
        input, button { padding: 8px; margin: 5px; }
        button { background: #007bff; color: white; border: none; border-radius: 3px; cursor: pointer; }
        button:hover { background: #0056b3; }
        .hidden { display: none; }
    </style>
</head>
<body>
    <div class="container">
        <h1>学生选课系统</h1>

        <div id="login-section" class="login-form">
            <h2>登录</h2>
            <input type="text" id="username" placeholder="用户名" required><br>
            <input type="password" id="password" placeholder="密码" required><br>
            <button onclick="login()">登录</button>
        </div>

        <div id="main-section" class="hidden">
            <h2>课程列表</h2>
            <div id="course-list" class="course-list"></div>
        </div>
    </div>

    <script>
        let currentUser = null;

        async function login() {
            const username = document.getElementById('username').value;
            const password = document.getElementById('password').value;

            const response = await fetch('/api/login', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: 'username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password)
            });

            const result = await response.json();
            if (result.success) {
                currentUser = result.data;
                document.getElementById('login-section').classList.add('hidden');
                document.getElementById('main-section').classList.remove('hidden');
                loadCourses();
            } else {
                alert('登录失败：' + result.message);
            }
        }

        async function loadCourses() {
            const response = await fetch('/api/courses');
            const result = await response.json();
            if (result.success) {
                displayCourses(result.data);
            }
        }

        function displayCourses(courses) {
            const container = document.getElementById('course-list');
            container.innerHTML = '';

            courses.forEach(course => {
                const div = document.createElement('div');
                div.className = 'course-item';
                div.innerHTML = `
                    <h3>${course.course_name} (${course.course_code})</h3>
                    <p>教师：${course.teacher_name} | 学分：${course.credits}</p>
                    <p>教室：${course.classroom} | 时间：${course.schedule}</p>
                    <p>已选/容量：${course.current_students}/${course.max_students}</p>
                    <button onclick="selectCourse(${course.id})">选课</button>
                `;
                container.appendChild(div);
            });
        }

        async function selectCourse(courseId) {
            const response = await fetch('/api/select-course', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: 'student_id=1&course_id=' + courseId
            });

            const result = await response.json();
            if (result.success) {
                alert('选课成功！');
                loadCourses();
            } else {
                alert('选课失败：' + result.message);
            }
        }
    </script>
</body>
</html>
)html";

    std::stringstream ss;
    ss << "HTTP/1.1 200 OK\r\n"
       << "Content-Type: text/html; charset=utf-8\r\n"
       << "Content-Length: " << html.length() << "\r\n"
       << "\r\n"
       << html;
    return ss.str();
}

std::string Server::createResponse(const std::string& status, const std::string& message, const std::string& data) {
    std::stringstream ss;
    std::string json_response;

    if (status == "success") {
        json_response = R"({"success":true,"message":")" + message + "\"";
        if (!data.empty()) {
            json_response += ",\"data\":" + data;
        }
        json_response += "}";
    } else {
        json_response = R"({"success":false,"message":")" + message + "\"}";
    }

    ss << "HTTP/1.1 200 OK\r\n"
       << "Content-Type: application/json; charset=utf-8\r\n"
       << "Access-Control-Allow-Origin: *\r\n"
       << "Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS\r\n"
       << "Access-Control-Allow-Headers: Content-Type\r\n"
       << "Content-Length: " << json_response.length() << "\r\n"
       << "\r\n"
       << json_response;
    return ss.str();
}